package service;

import model.User;
import utils.DatabaseUtil;
import utils.PasswordUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class UserService {

    /**
     * 根据ID获取用户信息
     * @param id 用户ID
     * @return 返回User对象，如果未找到则返回null
     */
    public User getUserById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();  // 获取数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) {  // 准备SQL语句

            pstmt.setInt(1, id);  // 设置SQL中的id参数为输入值
            ResultSet rs = pstmt.executeQuery();  // 执行查询

            if (rs.next()) {  // 如果找到结果
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));  // 注意：实际应用中不应返回密码
                user.setRole(rs.getString("role"));
                user.setStatus(rs.getInt("status"));
                user.setName(rs.getString("name"));
                user.setGender(rs.getString("gender"));
                user.setPhone(rs.getString("phone"));
                user.setEmail(rs.getString("email"));
                user.setCreatedAt(rs.getTimestamp("created_at"));
                user.setLastLogin(rs.getTimestamp("last_login"));
                return user;
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return null;  // 未找到用户时返回null
    }

    /**
     * 更新用户信息（仅更新name, role, status字段）
     * @param user 包含需要更新信息的User对象
     * @return 更新成功返回true，否则返回false
     */
    public boolean updateUser(User user) {
        String sql = "UPDATE users SET name = ?, role = ?, status = ? WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, user.getName());  // 设置SQL中的name参数为输入值
            pstmt.setString(2, user.getRole());  // 设置SQL中的role参数为输入值
            pstmt.setInt(3, user.getStatus());  // 设置SQL中的status参数为输入值
            pstmt.setInt(4, user.getId());  // 设置SQL中的id参数为输入值

            return pstmt.executeUpdate() > 0;  // 执行更新，如果受影响行数大于0则更新成功
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 更新失败返回false
        }
    }

    /**
     * 修改用户密码
     * @param userId 用户ID
     * @param newPassword 新密码
     * @return 修改成功返回true，否则返回false
     */
    public boolean updatePassword(int userId, String newPassword) {
        String sql = "UPDATE users SET password = ? WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            String encryptedPassword = PasswordUtil.encrypt(newPassword);  // 对新密码进行加密
            pstmt.setString(1, encryptedPassword);  // 设置SQL中的password参数为加密后的密码
            pstmt.setInt(2, userId);  // 设置SQL中的id参数为输入值

            return pstmt.executeUpdate() > 0;  // 执行更新，如果受影响行数大于0则更新成功
        } catch (Exception e) {
            e.printStackTrace();  // 打印异常信息
            return false;  // 更新失败返回false
        }
    }

    /**
     * 用户登录验证
     * @param username 用户名
     * @param password 密码
     * @return 登录成功返回User对象，否则返回null
     */
    private static final Map<String, User> userCache = new HashMap<>();  // 用户缓存

    public User login(String username, String password) {
        // 先检查缓存
        User cachedUser = userCache.get(username);
        if (cachedUser != null && verifyPassword(username, password)) {  // 如果缓存中有用户且密码验证成功
            // 检查用户状态
            if (cachedUser.getStatus() == 0) {
                throw new RuntimeException("该账号已被禁用，请联系管理员!");  // 用户被禁用时抛出异常
            }
            return cachedUser;  // 返回缓存中的用户对象
        }

        String sql = "SELECT * FROM users WHERE username = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, username);  // 设置SQL中的username参数为输入值
            ResultSet rs = stmt.executeQuery();  // 执行查询

            if (rs.next() && verifyPassword(username, password)) {  // 如果找到结果且密码验证成功
                // 检查用户状态
                int status = rs.getInt("status");
                if (status == 0) {
                    throw new RuntimeException("该账号已被禁用，请联系管理员!");  // 用户被禁用时抛出异常
                }

                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setRole(rs.getString("role"));
                user.setName(rs.getString("name"));
                user.setStatus(status);

                // 添加到缓存
                userCache.put(username, user);

                // 更新最后登录时间
                updateLastLogin(user.getId());

                return user;  // 返回用户对象
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return null;  // 登录失败返回null
    }

    /**
     * 更新最后登录时间
     * @param userId 用户ID
     */
    public void updateLastLogin(int userId) {
        String sql = "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, userId);  // 设置SQL中的id参数为输入值
            stmt.executeUpdate();  // 执行更新
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
    }

    /**
     * 用户注册
     * @param username 用户名
     * @param password 密码
     * @param role 角色
     * @param name 姓名
     * @param gender 性别
     * @param phone 手机号
     * @param email 邮箱
     * @return 注册成功返回true，否则返回false
     */
    public boolean register(String username, String password, String role,
                            String name, String gender, String phone, String email) {
        String sql = "INSERT INTO users (username, password, role, name, gender, phone, email) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, username);  // 设置SQL中的username参数为输入值
            pstmt.setString(2, PasswordUtil.encrypt(password));  // 设置SQL中的password参数为加密后的密码
            pstmt.setString(3, role);  // 设置SQL中的role参数为输入值
            pstmt.setString(4, name);  // 设置SQL中的name参数为输入值
            pstmt.setString(5, gender);  // 设置SQL中的gender参数为输入值
            pstmt.setString(6, phone);  // 设置SQL中的phone参数为输入值
            pstmt.setString(7, email);  // 设置SQL中的email参数为输入值

            return pstmt.executeUpdate() > 0;  // 执行插入，如果受影响行数大于0则插入成功
        } catch (SQLException e) {
            if (e.getErrorCode() == 1062) {
                System.out.println("用户名已存在");  // 用户名重复时的提示信息
            }
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 插入失败返回false
        } catch (Exception e) {
            e.printStackTrace();  // 打印其他异常信息
            return false;  // 插入失败返回false
        }
    }

    /**
     * 验证用户密码（通过用户名）
     * @param username 用户名
     * @param password 密码
     * @return 密码验证成功返回true，否则返回false
     */
    public boolean verifyPassword(String username, String password) {
        String sql = "SELECT password FROM users WHERE username = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, username);  // 设置SQL中的username参数为输入值
            ResultSet rs = pstmt.executeQuery();  // 执行查询

            if (rs.next()) {
                String storedPassword = rs.getString("password");  // 获取存储的密码
                return PasswordUtil.verify(password, storedPassword);  // 使用PasswordUtil工具类验证密码
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return false;  // 未找到用户或密码验证失败返回false
    }

    /**
     * 验证用户密码（通过用户ID）
     * @param userId 用户ID
     * @param password 密码
     * @return 密码验证成功返回true，否则返回false
     */
    public boolean verifyPassword(int userId, String password) {
        String sql = "SELECT password FROM users WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, userId);  // 设置SQL中的id参数为输入值
            ResultSet rs = pstmt.executeQuery();  // 执行查询

            if (rs.next()) {
                String storedPassword = rs.getString("password");  // 获取存储的密码
                return PasswordUtil.verify(password, storedPassword);  // 使用PasswordUtil工具类验证密码
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return false;  // 未找到用户或密码验证失败返回false
    }

    /**
     * 获取所有用户
     * @return 返回包含所有用户的List<User>对象
     */
    public List<User> getAllUsers() {
        List<User> users = new ArrayList<>();
        String sql = "SELECT * FROM users ORDER BY created_at DESC";  // 按创建时间降序排列

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            ResultSet rs = pstmt.executeQuery();  // 执行查询
            while (rs.next()) {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setRole(rs.getString("role"));
                user.setStatus(rs.getInt("status"));
                user.setName(rs.getString("name"));
                user.setGender(rs.getString("gender"));
                user.setPhone(rs.getString("phone"));
                user.setEmail(rs.getString("email"));
                user.setCreatedAt(rs.getTimestamp("created_at"));
                user.setLastLogin(rs.getTimestamp("last_login"));
                users.add(user);  // 将用户对象添加到列表中
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return users;  // 返回用户列表
    }

    /**
     * 创建新用户（仅包含username, password, role字段）
     * @param username 用户名
     * @param password 密码
     * @param role 角色
     * @return 创建成功返回true，否则返回false
     */
    public boolean createUser(String username, String password, String role) {
        String sql = "INSERT INTO users (username, password, role, name, status, created_at) " +
                "VALUES (?, ?, ?, ?, 1, CURRENT_TIMESTAMP)";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, username);  // 设置SQL中的username参数为输入值
            pstmt.setString(2, PasswordUtil.encrypt(password));  // 设置SQL中的password参数为加密后的密码
            pstmt.setString(3, role);  // 设置SQL中的role参数为输入值
            pstmt.setString(4, username);  // 默认使用 username 作为 name

            return pstmt.executeUpdate() > 0;  // 执行插入，如果受影响行数大于0则插入成功
        } catch (SQLException e) {
            if (e.getErrorCode() == 1062) {
                System.out.println("用户名已存在");  // 用户名重复时的提示信息
            }
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 插入失败返回false
        } catch (Exception e) {
            e.printStackTrace();  // 打印其他异常信息
            return false;  // 插入失败返回false
        }
    }

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 删除成功返回true，否则返回false
     */
    public boolean deleteUser(int userId) {
        String sql = "DELETE FROM users WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, userId);  // 设置SQL中的id参数为输入值
            return pstmt.executeUpdate() > 0;  // 执行删除，如果受影响行数大于0则删除成功
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 删除失败返回false
        }
    }

    /**
     * 添加用户（重载方法，包含更多字段）
     * @param username 用户名
     * @param password 密码
     * @param role 角色
     * @param name 姓名
     * @return 添加成功返回true，否则返回false
     */
    public boolean addUser(String username, String password, String role,String name) {
        String sql = "INSERT INTO users (username, password, role, name, status, created_at) " +
                "VALUES (?, ?, ?, ?, 1, CURRENT_TIMESTAMP)";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, username);  // 设置SQL中的username参数为输入值
            stmt.setString(2, PasswordUtil.encrypt(password));  // 设置SQL中的password参数为加密后的密码
            stmt.setString(3, role);  // 设置SQL中的role参数为输入值
            stmt.setString(4, name);  // 设置SQL中的name参数为输入值

            return stmt.executeUpdate() > 0;  // 执行插入，如果受影响行数大于0则插入成功
        } catch (SQLException e) {
            if (e.getErrorCode() == 1062) {
                System.out.println("用户名已存在");  // 用户名重复时的提示信息
            }
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 插入失败返回false
        } catch (Exception e) {
            e.printStackTrace();  // 打印其他异常信息
            return false;  // 插入失败返回false
        }
    }

    /**
     * 获取用户个人资料
     * @param userId 用户ID
     * @return 返回包含用户个人资料信息的Map<String, String>对象
     */
    public Map<String, String> getPersonalInfo(int userId) {
        String sql = "SELECT * FROM users WHERE id = ?";
        Map<String, String> info = new HashMap<>();

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, userId);  // 设置SQL中的id参数为输入值
            ResultSet rs = stmt.executeQuery();  // 执行查询

            if (rs.next()) {
                info.put("name", rs.getString("name"));  // 获取并存储用户姓名
                info.put("gender", rs.getString("gender"));  // 获取并存储用户性别
                info.put("phone", rs.getString("phone"));  // 获取并存储用户手机号
                info.put("email", rs.getString("email"));  // 获取并存储用户邮箱
            }
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
        }
        return info;  // 返回包含用户个人资料信息的Map对象
    }

    /**
     * 更新用户个人资料
     * @param userId 用户ID
     * @param info 包含需要更新信息的Map<String, String>对象
     * @return 更新成功返回true，否则返回false
     */
    public boolean updatePersonalInfo(int userId, Map<String, String> info) {
        String sql = "UPDATE users SET name = ?, gender = ?, phone = ?, email = ? WHERE id = ?";

        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, info.get("name"));  // 设置SQL中的name参数为输入值
            stmt.setString(2, info.get("gender"));  // 设置SQL中的gender参数为输入值
            stmt.setString(3, info.get("phone"));  // 设置SQL中的phone参数为输入值
            stmt.setString(4, info.get("email"));  // 设置SQL中的email参数为输入值
            stmt.setInt(5, userId);  // 设置SQL中的id参数为输入值

            return stmt.executeUpdate() > 0;  // 执行更新，如果受影响行数大于0则更新成功
        } catch (SQLException e) {
            e.printStackTrace();  // 打印SQL异常信息
            return false;  // 更新失败返回false
        }
    }
}
